using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Arcadium.Graphics;

namespace Arcadium.Screens.Menus.MenuHelpers
{
    class Cloud
    {
        #region Field

        private Texture2D texture;
        private Color color;
        private float speed;
        private Vector2 position;

        #endregion

        #region Properties

        public Texture2D Texture { get { return texture; } }

        public Vector2 Position { get { return position; } }

        public Color Color { get { return color; } }

        #endregion

        #region Initialization

        public Cloud(Texture2D texture, Color color, Vector2 startingPosition, float speed)
        {
            this.texture = texture;
            this.color = color;
            this.position = startingPosition;
            this.speed = speed;
        }

        #endregion

        #region Update

        internal bool Update(GameTime gameTime)
        {
            position.X -= speed * 125 * (float)gameTime.ElapsedGameTime.TotalSeconds;
            return position.X + texture.Width < 0;
        }

        #endregion
    }

    class BackgroundScreen : GameScreen
    {
        #region Field

        private static Random random = new Random();

        private ContentManager content;

        private static Color backgroundColor = new Color(200, 255, 255);

        private static Color[] cloudColors = new Color[] { Color.White, new Color(255, 250, 250), new Color(220, 220, 255) };
        private static Texture2D[] cloudTextures;

        private List<Cloud> clouds = new List<Cloud>();

        #endregion

        #region Initialization

        public BackgroundScreen()
        {
            TransitionOnTime = TimeSpan.FromSeconds(.5);
            TransitionOffTime = TimeSpan.FromSeconds(.5);
        }

        /// <summary>
        /// Loads graphics content for this screen. The background texture is quite
        /// big, so we use our own local ContentManager to load it. This allows us
        /// to unload before going from the menus into the game itself, wheras if we
        /// used the shared ContentManager provided by the Game class, the content
        /// would remain loaded forever.
        /// </summary>
        public override void LoadContent()
        {
            if (content == null)
                content = new ContentManager(ScreenManager.Game.Services, "Content");

            int cloudCount = 1;
            cloudTextures = new Texture2D[cloudCount];
            for (int i = 0; i < cloudCount; i++)
            {
                cloudTextures[i] = content.Load<Texture2D>(
                    "Menu\\Background\\cloud" + i);
            }

            // Add some preloaded clouds
            for (int i = 0; i < 10; i++)
            {
                Texture2D texture = cloudTextures[random.Next(cloudTextures.Length)];
                Color color = cloudColors[random.Next(cloudColors.Length)];
                color.A = (byte)(random.Next(200) + 55);
                Vector2 startingPosition = new Vector2(
                    (float)random.NextDouble() * View.ScreenWidth,
                    (float)random.NextDouble() * View.ScreenHeight);
                float speed = ((float)random.NextDouble() - .5f) / 5 + 1;
                clouds.Add(new Cloud(texture, color, startingPosition, speed));
            }
        }

        /// <summary>
        /// Unloads graphics content for this screen.
        /// </summary>
        public override void UnloadContent()
        {
            content.Unload();
        }

        #endregion

        #region Update and Draw

        /// <summary>
        /// Updates the background screen. Unlike most screens, this should not
        /// transition off even if it has been covered by another screen: it is
        /// supposed to be covered, after all! This overload forces the
        /// coveredByOtherScreen parameter to false in order to stop the base
        /// Update method wanting to transition off.
        /// </summary>
        public override void Update(GameTime gameTime, bool otherScreenHasFocus,
                                                       bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, false);

            if (random.NextDouble() < .01)
            {
                Texture2D texture = cloudTextures[random.Next(cloudTextures.Length)];
                Color color = cloudColors[random.Next(cloudColors.Length)];
                color.A = (byte)(random.Next(200) + 55);
                Vector2 startingPosition = new Vector2(View.ScreenWidth,
                    (float)random.NextDouble() * View.ScreenHeight);
                float speed = ((float)random.NextDouble() - .5f) / 5 + 1;
                clouds.Add(new Cloud(texture, color, startingPosition, speed));
            }

            for (int i = 0; i < clouds.Count; i++)
            {
                if (clouds[i].Update(gameTime))
                {
                    clouds.Remove(clouds[i--]);
                }
            }
        }

        /// <summary>
        /// Draws the background screen.
        /// </summary>
        public override void Draw(GameTime gameTime)
        {
            SpriteBatch spriteBatch = ViewResource.SpriteBatch;
            spriteBatch.Begin();
            spriteBatch.Draw(ViewResource.BlankTexture, View.ScreenRect, null, 
                backgroundColor * TransitionAlpha, 0, 
                Vector2.Zero, SpriteEffects.None, 0);
            foreach (Cloud cloud in clouds)
            {
                spriteBatch.Draw(cloud.Texture, View.Adjust(cloud.Position), null,
                    cloud.Color * TransitionAlpha, 0, 
                    Vector2.Zero, View.ScreenScale, SpriteEffects.None, 1);
            }
            spriteBatch.End();
        }

        #endregion
    }
}
